Java/ActionScript – String.split(), 及For in 小结

Categories: Java; Tagged with: ; @ February 15th, 2009 11:36

Java 5.0中:

public String[] split(String regex)

    根据给定正则表达式的匹配拆分此字符串。

    该方法的作用就像是使用给定的表达式和限制参数 0 来调用两参数 split 方法。因此,所得数组中不包括结尾空字符串。

    例如,字符串 "boo:and:foo" 使用这些表达式可生成以下结果:

        Regex     结果
        :     { "boo", "and", "foo" }
        o     { "b", "", ":and:f" }

    参数:
        regex – 定界正则表达式
    返回:
        字符串数组,它是根据给定正则表达式的匹配拆分此字符串确定的
    抛出:
        PatternSyntaxException – 如果正则表达式的语法无效
    从以下版本开始:
        1.4

 

注意: 使用转义字符.

如:

		String str = "192.168.1.1";
		String[] strs = str.split("\\.");
		for (String string : strs) {
			System.out.println(string);
		}

输出:

192

168

1

1

ActionScript中:

			var str:String = "192.168.1.1";
			var strsArray = str.split("\.");//str.split(".");
			for each(var s:String in strsArray) {
				trace(s);
			}
			for(var s:String in strsArray) {
				trace("for in " + strsArray);
			}

输出信息:

for-each-in 192

for-each-in 168

for-each-in 1

for-each-in 1

for in 0

for in 1

for in 2

for in 3

另外, 在AS中, for in 和for each in 的区别:

for-each-in 类似于Java5.0之后的for-in, 如上所使用

在AS中for-in的循环迭代于变量名中, 如上AS代码中的for-in输出的是Array的index[下标], 如果要打印value, 则应使用 在trace中使用strsArray[s].

Java内部类使用总结

Categories: Java; Tagged with: ; @ February 13th, 2009 20:44

顶层类只能处于Public跟默认访问级别. 而内部类可以处于任意访问级别.

A 实例内部类:

  • 在创建实例内部类实例时, 外部类的实力必须已经存在.
  • 实例内部类自动持有外部类实例的引用
  • 一个外部类可以有多个内部类 因此不允许外部类直接调用内部类方法或属性. 而内部类进对应一个外部类, 因此可以直接使用外部类的引用.
  • 在实例内部类中不能定义静态成员, 只能定义实例成员.
  • 当内部类与外部类有同名的成员时,如age, 在内部类中直接使用age或this.age表示inner2内age 而OnlyForTest.this.age表示外部类中的age.

B 静态内部类:

  • 静态内部类的实例不会自动持有外部类的特定实例的引用, 因此在创建内部类的实例时, 不必创建外部类的实例.
  • 静态内部类可以直接访问外部类的静态成员, 如果要访问外部类的实例成员, 就必须通过外部类的实例去访问
  • 静态内部类中可以定义静态成员和实例成员
  • 客户类可以通过完整的类名直接访问静态内部类的静态成员.

局部内部类:

  • 与局部变量一样, 不能被访问控制符修饰.
  • 只能在当前方法中使用
  • 不能包含静态成员
  • 在局部类中定义的内部类也不能被访问控制符修饰
  • 局部内部类和实例内部类一样, 可以访问外部类的所有成员, 此外, 局部内部类还可以访问所在方法中的final类型的参数和变量.

匿名类:

  • 匿名类没有构造方法, 但是会调用父类的构造方法.
  • 匿名类尽管没有构造方法, 但是可以在匿名类中提供一段实例初始化代码
  • 除了可以在外部类的方法内定义匿名类之外, 还可以在生命一个成员变量时定义匿名类
  • 匿名类除了可以继承外, 还可以实现接口
  • 匿名类和局部内部类一样, 都可以访问外部类的所有成员, 如果匿名类位于一个方法中, 还可以访问方法内部的final类型的变量和参数

 

举例[实例内部类, 静态内部类]:

 

public class OnlyForTest {
	public static String staticOutMember = "Static Out Member";
	private String userName;
	private int age;
	//省略Getter/Setter
	
	public static void main(String[] args) {
		OnlyForTest oft = new OnlyForTest();
		//A1. 在创建实例内部类实例时, 外部类的实力必须已经存在.
		OnlyForTest.Inner inner = oft.new Inner();
		
		//A3. 一个外部类可以有多个内部类  因此不允许外部类直接调用内部类方法或属性, 在需要时, 使用内部类实例访问内部类成员
		//而内部类进对应一个外部类, 因此可以直接使用外部类的引用.
		oft.age = oft.new Inner2().age;
		
		inner.setOutInstanceNmae("tom");
		
		oft.new Inner2().print();
		
		//B1: 直接访问静态类静态成员, 不需创建实例.
		System.out.println(staticInnerClass.staticInnerMember);
		
		new staticInnerClass().printNmae();
	}
	
	class Inner {
		public void setOutInstanceNmae(String s){
			//A2. 实例内部类自动持有外部类实例的引用
			userName = s;
			System.out.println("内部类直接引用外部类实例 - 内部类赋值外部类成员 " + userName);
		}
	}//end of class Inner
	
	class Inner2 {
		int age= 2;
		//A4. 在实例内部类中不能定义静态成员, 只能定义实例成员.
		//报错!static int staticInt = 4;
		public void print() {
			System.out.println(userName);
			//A5. 当内部类与外部类有同名的成员时,如age
			//直接使用age或shis.age表示inner2内age
			//OnlyForTest.this.age表示外部类中的age
			System.out.println(age);
			System.out.println(OnlyForTest.this.age);
			//B2. 直接访问外部类的静态成员
			System.out.println(staticOutMember);
		}
	}//end of class Inner2
	
	static class staticInnerClass {
		public static String staticInnerMember = "Static Inner Member";
		public void printNmae() {
			//B3:静态内部类在访问外部类实例变量时, 必须通过外部实例
			OnlyForTest o = new OnlyForTest();
			o.userName = "set by Static Inner Class";
			System.out.println(o.userName);
		}
	}//end of staticInnerClass
}

编译后的Class文件:

image

DeCompiler之后 Inner的构造函数:

    OnlyForTest$Inner2()
    {
        this$0 = OnlyForTest.this;
        super();
        age = 2;
    }

可见, 每个inner实例都会自动包含一个外部类OnlyForTest的引用

而staticInnerClass类的构造函数为空, 因此他的实例不会自动引用外部类

从Decompile的Class文件来看, 对JVM来说, 无所谓内外类之分, 他们都是Class, 只是内部类会自动引用外部类实例 或是 其他特定的功能而已.

Servlet实践 2-2

Categories: Java; Tagged with: ; @ February 13th, 2009 20:24

Login设计

当Request进入时, 先通过request.getSession(false)检查Session是否存在, 如果存在则表明已经登录,则通过sendRedirect(Calc.URL_MAIN)跳转到主页面
Session不存在时, 通过request.getParameter()方法获得输入的用于名及密码, 通过ServletContext的get Parameter()方法获得用户名及密码, 如果相互都equals, 则增加Session, 登录成功, 转入主页面. 如果不equals, 则提示输入有误, 重新输入
重要方法:

response.sendRedirect();
request.getParameter();
getServletContext().getAttribute();

package com.insprise.servletStu;
//省略import
public class Login extends HttpServlet {
      public static final String USER_NAME = "userName";
	public static final String PASS_WORD = "passWord";
	private static final long serialVersionUID = 1L;
	private static final String INPUT_USER_NAME = "inputUserName";
	private static final String INPUT_PASSWORD = "inputPassWord";
	private String passWord;
      private String name;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		name = (String) getServletContext().getAttribute(USER_NAME);
		passWord = (String) getServletContext().getAttribute(PASS_WORD);
		HttpSession session = request.getSession(false);
		if (session != null) {
			response.sendRedirect(Calc.URL_MAIN);//如果已经登录后再次打开登录页面, 跳转到主界面
			return;
		} else {
			response.setContentType("text/html");
			response.setCharacterEncoding("utf-8");
			PrintWriter out = response.getWriter();

			if (request.getParameter(INPUT_USER_NAME) != null) {
				String inputUserName = request.getParameter(INPUT_USER_NAME);
				String inputPassWord = request.getParameter(INPUT_PASSWORD);
				if (inputUserName.equals(USER_NAME) && inputPassWord.equals(passWord)) {
					request.getSession().setAttribute(Calc.CURRENT_USER, USER_NAME);
					response.sendRedirect(Calc.URL_MAIN);
					return;
				} else {
					//登录失败
				}
			} else {
				//省略若干println…
	}
	//省略doPost
}

 

 

CalcListener实现

该类实现ServletContextListener接口, 在Application初始化时, contextInitialized(ServletContextEvent sce)方法会被自动呼叫, 在此之后, Filter与Servlet开始初始化.

使用getServletContext().getInitParameter()方法获得web.xml中<context-param>标签中的内容.

使用ServletContext的setAttribute方法为获得用户名及密码, 并作为Attribute加入到ServletContext中

重要方法:

sce.getServletContext();

ServletContext.getInitParameter();

ServletContext. setAttribute();

public class CalcListener implements ServletContextListener {

private static Logger log = Logger.getLogger(CalcListener.class); 

public void contextInitialized(ServletContextEvent sce) {

log.info("Context Started!" + sce.getServletContext());

ServletContext context = sce.getServletContext();

Calc.MAX_CALCULATION_TIMES_PER_SESSION = Integer.parseInt(context.getInitParameter(Calc.MAX_CALCULATIONAS_PER_SESSION));

Calc.MAX_CALCULATION_TIMES_PER_SESSION = Integer.parseInt(context.getInitParameter(Calc.MAX_CALCULATIONAS_PER_SESSION));

//读取到用户名及密码, 加入到Context Attribute中

context.setAttribute(Login.USER_NAME, new String(context.getInitParameter(Login.USER_NAME)));

context.setAttribute(Login.PASS_WORD, new String(context.getInitParameter(Login.PASS_WORD)));
}

}

 

2.4 抓图

clip_image002 clip_image004

clip_image006

Servlet实践 2-1

Categories: Java; Tagged with: ; @ February 13th, 2009 20:21

实践

2.1 需求及用例

创建一个简单的计算器, 当用户输入整数时, 输出其平方值. 但用户需要登录才能进行操作, 用户的登录信息放在web.xml中, 每次登录用户可以使用该计算器三次, 三次使用结束后, 提示用户推出后重新登录继续使用.

User Case 用例

登录系统

Brief description

登录系统

Scope/Level

AthenaES/User goal

Primary actor/role

Root

Minimal & Success Guarantees 保证

Minimal: The system logs how far it may get
Success:登录成功

Preconditions 前提

Triggers 引发条件

用户打开登录界面

Main Success Scenario 成功场景

1. 系统提示用户输入用户名及密码
2. 用户输入用户名及密码
3. 系统核对用户名及密码
4. 系统提示用户登录成功

Extension 扩展 #1

3a: 系统无法核实用户身份, 提示其用户名或密码错误, 并提示用户重新输入

Notes and Issues

User Case 用例

计算平方

Brief description

计算平方

Scope/Level

AthenaES/User goal

Primary actor/role

Root

Minimal & Success Guarantees 保证

Minimal: The system logs how far it may get
Success: 成功显示结果

Preconditions 前提

Actor is logged in

Triggers 引发条件

用户点击”计算”

Main Success Scenario 成功场景

1. 确认用户使用次数未达到上限
2. 用户输入整数
3. 用户点击”计算”
4. 系统确认输入合法
5. 系统计算平方值, 系统将用户使用次数加一, 系统显示结果, 提示用户使用次数.
用户重复步骤1~5 , 直到用户关闭程序或使用次数达到上限

Extension 扩展 #1

1a: 用户使用次数达到上限, 系统提示用户重新登陆后继续使用

Extension 扩展 #2

4a: 系统检测到用户输入不合法, 系统提示用户重新输入 用户重新进行2~4

Notes and Issues

2. 2 数据分析:


1. ServltContext
层次的数据: 由于用户名及最大限制次数等信息在整个Servlet进程中都会被使用, 因此使用Context的Listener来实现.

2. Session层次的数据: 用户本次登录已使用次数应记录在Seesion中, 在当前Session中使用

3. Request层次的数据: 用户输入的数值尽在当前Request中使用

2. 3 具体实现

</>

Calc主页面实现:

首先检查Session是否存在, 不存在则跳转到登录界面.
Session存在, 则通过session.getAttribute()获得该用户在当前Session中的使用次数, 如果为Null, 则设置为零, setAttribute.
如果不为Null, 则判断是否小于MAX_CALCULATION_TIMES_PER_SESSION, 如果大于三次则提示其退出登录重新登录继续使用.
小于MAX_CALCULATION_TIMES_PER_SESSION则呼叫proccessRequet()方法输出计算器. 该方法将会调用calculator()方法, 该方法将返回输入值的平方,同时将Session中的使用次数加一.
重要方法:
request.getSession(false);//获得Session, 如果不存在, 则返回null
session.getAttribute(ACCESS_COUNT);
session.setAttribute(ACCESS_COUNT, accessCount);
request.getSession().invalidate(); //
清空session

package com.insprise.servletStu;
//省略import
public class Calc extends HttpServlet {
	public static final String MAX_CALCULATIONAS_PER_SESSION = “maxNumber”; // 最大使用次数的Key
	public static int MAX_CALCULATION_TIMES_PER_SESSION; // 最大使用次数
	public static final String CURRENT_USER = “currentUser”; // 当前用户
	public static final String URL_MAIN = “./Calc”; // 主页面
	public static final String URL_LOGIN = “./Login”; // 登录页面
	public static final String URL_LOGOUT = “./Logout”; // 注销页面
	private static final String ACCESS_COUNT = “accessCount”; // 使用次数
	private static final String INPUT_INT = “inputInt”;
	private static Logger log = Logger.getLogger(Calc.class);
	private static final int MAX_INT = 46340; // Math.sqrt(Integer.MAX_VALUE)

	private HttpSession session;
	private Integer accessCount; // 使用次数

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		session = request.getSession(false);
		if (validatUser(session)) { // 已登录
			accessCount = (Integer) session.getAttribute(ACCESS_COUNT);
			if (accessCount == null) { // 如果Session中不存在accessCount, 则表明其为新登录用户,
				// 赋值为0;
				accessCount = 0;
				session.setAttribute(ACCESS_COUNT, accessCount);
			}
			if (checkUseTimes(accessCount)) { // 已登录, 且使用次数在限制之内, 进行操作.
				proccessRequet(request, response);

			} else { // 已登录, 但使用次数操过限制,提示用户重新登陆.
				accessOverTime(request, response);
			}
		} else { // 未登录
			response.sendRedirect(URL_LOGIN);
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
		doGet(request, response);
	}

	// 检查用户是否已登录
	private boolean validatUser(HttpSession s) {
		if (session != null) {
			return true;
		}
		return false;
	}

	// 检查用户使用次数是否超过限制
	private boolean checkUseTimes(Integer number) {
		//省略
	}

	// 使用次数超过限制之后 提示其登录;
	private void accessOverTime(HttpServletRequest request, HttpServletResponse response) throws IOException {
		request.getSession().invalidate();
		response.getWriter().println("本次登录已使用完毕, 请重新登录");
		return;
	}

	// 获得输入数值, 计算结果, 返回信息
	private void proccessRequet(HttpServletRequest request, HttpServletResponse response) throws IOException {
		Integer i;
		String title = "求整数平方";

		response.setContentType("text/html");
		response.setCharacterEncoding("utf-8");
		// 不使用缓存 在点击推出后 按后退按钮时 不会出现缓存中的内容.
		response.setHeader("Cache-Control", "no-store");
		response.setDateHeader("Expires", 0);
		response.setHeader("Pragma", "no-cache");

		PrintWriter out = response.getWriter();
		out.println(ServletUtilities.headwithTitle(title));
		out.println("

" + title + "


"); out.println("

当前用户: " + session.getAttribute(CURRENT_USER) + " [退出]

"); String numberString = request.getParameter(INPUT_INT); if (numberString != null) { try { out.println("

" + i + " 的平方是: " + calculator(i) + "

"); log.info("累计第[" + accessCount + "]次使用, 本次计算的参数为: " + i); } catch (Exception e) { out.println("您可能输入的不是整数 或您输入的整数绝对值过大

请输入: 一个绝对值小于" + MAX_INT + " 的整数

"); } } out.println("

您总共可以使用 " + MAX_CALCULATION_TIMES_PER_SESSION + "次, 您已累计使用:" + accessCount + "次
"); // 最后一次运行时, 停止输出Form; if (accessCount.equals(MAX_CALCULATION_TIMES_PER_SESSION)) { out.println("已达到最大使用次数限制, 请退出后重新登陆"); return; } printForm(out); out.println(""); } // 计算 private int calculator(int i) { accessCount = new Integer(accessCount.intValue() + 1); // 使用次数增加一次 session.setAttribute("accessCount", accessCount); return i * i; } // 打印一个Form private void printForm(PrintWriter out) { out.print("


"); out.println("请输入一个整数: "); out.println("
"); out.println(" "); } }

Servlet学习总结 – Servlet Reference

Categories: Java; Tagged with: ; @ February 13th, 2009 20:12

2009-2-13 14-56-18

很简单的几个概念, 其他还是OO.

A: Request常用方法

request中获取参数

方法

说明

getParameter(String name);

获得request中参数名name对应的值, 如果不存在该参数, 则返回Null – 注意: 名称大小写敏感

GetParameterNames

返回一个枚举对象, 包含了所在request中的所有参数名, 如果request没有参数, 该方法返回一个空的枚举

GetParameterValues(String name)

返回一个Sting[], 包含参数所对应的所有的值, 如果参数不存在,则返回Null.

getParameterMap

返回一个Map对象, 以参数名称为Key(String), 参数对应值为Value(类型String[])

getSession()

获得当前Session

Response中输出信息

方法

说明

setContentType(String type)

声明返回数据的MIME类型

setCharacterEncoding(String charset)

声明Response的编码

getWriter();

返回一个PrintWriter, 可通过该对象的print 或printlin方法向客户端发送字符串数据流

sendRedirect(String location)

设置转向 – 转到某地址

B: Session常用方法:

方法

说明

getServletContext()

获得Session所在的ServletContext对象

getAttribute(String name)

返回该Session中name对应的Attribute对象, 如果没有则返回null

getAttributeNames()

返回一个枚举, 包括Seesion中所有的Attribut 对应的name,

setAttribute(String name, Object value)

在Session中加入Attribute

invalidate()

销毁Session

C: ServeletContext常用方法

方法

说明

getInitParameter(String name)

返回一个String, 包含对应的初始化参数, 如果不存在则返回null, init参数可在web.xml中使用<context-param>设定

getInitParameterNames()

返回由所有的init参数名称组成的枚举, 如果不存在任何init参数, 则返回空的枚举

getAttribute(String name)

返回运行时设定相应的Attribute 对象, 如不存在则返回null

getAttributeNames()

返回一个枚举, 包含所有Attribute的name, 如果不存在任何Attribue, 则返回一个空的枚举

setAttribute(String name, Object object)

在运行时增加Attribute

removeAttribute(String name)

删除对应name的Attribute

D: Servlet框架理解

Servlet通过IoC(Inversion of Control意为控制反转)将代码交给框架来执行. 因此只需要在Servlet类中扩展HttpServlet, 覆盖doGet, doPost等方法, 就可成功创建并执行一个Servlet. 在有客户Request时, 将由Service方法分析Request, 并交由对应方法处理, 如Get交由doGet方法处理.

Listener: Servlet中的listener类似于AS中的Event kind, 在Listener支持的事件 – 如Servlet初始化完毕, Session初始化, Request Destory,等, 在这些事件发生后, 将自动运行相应的方法(IoC)

如果需要Listener或Filter, 则在编写好相应的类之后, 加入到web.xml描述文件中.

Servlet 的数据层次:
1. ServletContext: Application初始化时会呼叫Listener contextInitialized(), 可以在该方法中获得或设定ServletContext生命周期内的数据. 如可以通过getInitParameter来获取web.xml中定义好的初始化参数, 也可以通过setAttribute方法设定Attribute, 这些Attribute将在整个Servlet生命周期内有效.

2. HttpSession: 当获得Session之后, 可以进行setAttribute等方法设定Session’的Attribute – 在该Session中有效

3. HttpRequest: 在doGet, doPost等方法中, 可以通过request. get Parameter(String name)等方法来获得request中的数据, 这些数据仅对当前的这个Request有效

Newer Posts <-> Older Posts



// Proudly powered by Apache, PHP, MySQL, WordPress, Bootstrap, etc,.